package student;

import java.util.*;

public class Student implements Comparable<Student> {

	public enum Grade {
		A(4), B(3), C(2), D(1), F(0);
		private int points;

		Grade(int points) {
			this.points = points;
		}

		int getPoints() {
			return points;
		}
	}

	private String name;
	private String firstName = "";
	private String middleName = "";
	private String lastName;
	private int credits;
	static final int CREDITS_REQUIRED_FOR_FULL_TIME = 12;
	static final String IN_STATE = "CO";
	private String state = "";
	private ArrayList<Grade> grades = new ArrayList<Grade>();
	private GradingStrategy gradingStrategy = new BasicGradingStrategy();
	private List<Integer> charges = new ArrayList<Integer>();

	public String getName() {
		return name;
	}

	public Student(String fullName) {
		this.name = fullName;
		credits = 0;
		List<String> nameParts = split(fullName);
		setName(nameParts);
	}
	
	private List<String> split(String fullName){
		List<String> results = new ArrayList<String>();
		for (String name: fullName.split(" ")){
			results.add(name);
		}
		return results;
	}

	private void setName(List<String> nameParts) {
		this.lastName = removeLast(nameParts);
		String name = removeLast(nameParts);
		if (nameParts.isEmpty()) {
			this.firstName = name;
		} else {
			this.middleName = name;
			this.firstName = removeLast(nameParts);
		}
	}

	private String removeLast(List<String> list) {
		if (list.isEmpty()) {
			return "";
		}
		return list.remove(list.size() - 1);
	}

	public String getFirstName() {
		return firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public String getLastName() {
		return lastName;
	}

	boolean isFullTime() {
		return credits >= CREDITS_REQUIRED_FOR_FULL_TIME;
	}

	public Object getCredits() {
		return credits;
	}

	public void addCredits(int credits) {
		this.credits += credits;
	}

	void setState(String state) {
		this.state = state;
	}

	boolean isInState() {
		return state.equals(Student.IN_STATE);
	}

	public void addGrade(Grade grade) {
		grades.add(grade);
	}

	public double getGpa() {
		if (grades.isEmpty())
			return 0.0;
		double total = 0.0;
		for (Grade grade : grades)
			total += gradingStrategy.getGradePointsFor(grade);
		return total / grades.size();
	}

	int gradePointsFor(Grade grade) {
		return gradingStrategy.getGradePointsFor(grade);
	}

	void setGradingStrategy(GradingStrategy gradingStrategy) {
		this.gradingStrategy = gradingStrategy;
	}

	@Override
	public int compareTo(Student o) {
		throw new UnsupportedOperationException();
	}
	
	public void addCharge(int charge) {
		charges.add(new Integer(charge));
	}
	
	public int totalCharges() {
		int total = 0;
		for (Integer charge: charges) {
			total += charge.intValue();
		}
		return total;
	}
	
}
